#include <SoftwareSerial.h>
#include <PString.h>
#include <string.h>

#define TX_PIN 13
#define RX_PIN 12
SoftwareSerial ctlSerial(RX_PIN, TX_PIN);

// map Arduino Uno pins to DL1414
const byte PIN_WR = 5; // Arduino D5 -> DL1414 WR (3)
const byte PIN_A[2] = {
  6, // Arduino D5 -> DL1414 A1 (4)  
  4, // Arduino D6 -> DL1414 A0 (5)
}; 

// Arduino Dx pins to DL1414 Dx (pin)
const byte PIN_D[7] = {
  11, // Arduino D11 -> DL1414 D0 (8)
  10, // Arduino D10 -> DL1414 D1 (9)
  9, // Arduino D9 -> DL1414 D2 (10)
  8, // Arduino D8 -> DL1414 D3 (11) 
  3, // Arduino D3 -> DL1414 D4 (2
  2, // Arduino D2 -> DL1414 D5 (1)
  7 // Arduino D7 -> DL1414 D6 (12)
};

// Safe write cycle gap, in ms
const int WRITE_CYCLE_GAP = 1;

void setup() {
  Serial.begin(9600);
  // initialize all pins
  for (int i=2; i<=11; i++) {
    pinMode(i, OUTPUT);
  }
  pinMode(RX_PIN, INPUT);
  pinMode(TX_PIN, OUTPUT);
  ctlSerial.begin(9600);
  ctlSerial.listen();
  // pull WR line high as baseline - 
  // falling edge triggers write
  digitalWrite(PIN_WR,HIGH); 
}

void printDigit(byte digit, byte digitIdx) {
  byte ASCII_ZERO_OFFSET = 0x30;
  printChar(digit + ASCII_ZERO_OFFSET, digitIdx);
}

// look up character code for digit 
// and write to DL1414 data pins
void printChar(char charCode, byte digitIdx) {
  // Per DL1414 spec, write cycle occurs as:
  // 1. write A0/A1
  // 2. pull WR low
  // 3. write character code into D0..D6
  // all write cycle delay parameters are < 100ns, so a 1 ms wait is used as 
  // as generous transition time
  // Write digit index address (A0/A1 pins, (1st write cycle edge) 
  digitalWrite(PIN_A[0],bitRead(digitIdx,0));
  digitalWrite(PIN_A[1],bitRead(digitIdx,1));
  // Pull WR pin low per DL1414 spec (2nd write cycle edge) 
  delay(WRITE_CYCLE_GAP);
  digitalWrite(PIN_WR,LOW);
  // Shift character code bits out and write into Dx pins
  // (3rd write cycle edge)
  delay(WRITE_CYCLE_GAP);
  for (int j=0; j<=6; j++) {  
    digitalWrite(PIN_D[j],bitRead(charCode,j));
  }
  // Pull WR pin high per DL1414 spec (4th write cycle edge) 
  delay(WRITE_CYCLE_GAP);
  digitalWrite(PIN_WR,HIGH);
  delay(WRITE_CYCLE_GAP);
}

void blink(int delayTime) {
  digitalWrite(13,HIGH);
  delay(delayTime);
  digitalWrite(13,LOW);    
  delay(delayTime);
}

void showString(char s[]) {
  byte i,j;
  for (j=0; j < strlen(s)-3; j++) {
    for (i=0; i <= 3; i++) {
      char p = s[i+j];
      if (p == '\0') return;
      printChar(s[i+j],3-i);
    }
    delay(200);
    if (j==0) {
      delay(500);
    }
  }
}

void showTemp(char s[]) {
  char disp[5];
  strncpy(disp,s,4);
  disp[4]=0;
  showString(disp);
}

char xtest[] = "THIS IS YET ANOTHER 3.5";

/*
char* dtostrf 	( 	double  	__val,
 		signed char  	__width,
 		unsigned char  	__prec,
 		char *  	__s 
 	) 	
 */

#define BUFFER_SIZE 128
String buffer;
char pad[BUFFER_SIZE];
byte sync = 0;
int i;

void loop() {
  //sprintf(buffer,"THIS IS A %s TEST %d, %f","REAL",1,3.4f);
  while (1) {
    if (ctlSerial.available() && i<BUFFER_SIZE) {
      char c = ctlSerial.read();
      //Serial.print("i,c="); Serial.print(i); Serial.print(','); Serial.println(c);
      if (c == '@') {
       //Serial.println("buffer=" + buffer);
        //Serial.println("found @, backtracking for |");
        if (i > 13) {
          int pos = buffer.lastIndexOf('|');
          if (pos == -1) {
            //Serial.print("| not found in buffer");
          } else {
            //Serial.print("found |, at #"); Serial.println(pos);
            buffer.substring(pos+1).toCharArray(pad,pos+1-i);
            Serial.print("temp="); Serial.println(pad);
            showTemp(pad);
          }
        }       
        i=0;
        buffer = "";
        pad[0]=0;
      } else {
        buffer = buffer + c;
        //Serial.println("Appended. buffer=" + buffer);
        i++;
      }
    }
  }
}




